﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ttlang.semantic
{
    public class TTNameSpace : IContainer
    {
        Dictionary<string, TTNameSpace> _namespaces;
        Dictionary<string, TTType> _types;
        Dictionary<string, TTMethod> _methods;
        Dictionary<string, TTVar> _vars;
        List<string> _comments;

        public TTNameSpace(Module module, IContainer parent, string name)
        {
            this.module = module;
            this.name = name;
            parentContainer = parent;
        }
        public ContainerType type => ContainerType.NameSpace;

        public string name
        {
            get;
            private set;
        }

        public string fullname
        {
            get
            {
                if (parentContainer != null && string.IsNullOrEmpty(parentContainer.fullname) == false)
                {
                    return parentContainer.fullname + "." + this.name;
                }
                else
                {
                    return this.name;
                }
            }
        }
        public Module module
        {
            get;
            private set;
        }

        public IContainer parentContainer
        {
            get;
            private set;
        }

        public IReadOnlyDictionary<string, TTNameSpace> namespaces
        {
            get
            {
                return _namespaces;
            }
        }
        public IList<string> comments
        {
            get
            {
                return _comments;
            }
        }
        public void AddComment(string comment)
        {
            if (_comments == null)
                _comments = new List<string>();
            _comments.Add(comment);
        }
        public IReadOnlyDictionary<string, TTType> types
        {
            get
            {
                return _types;
            }
        }

        public IReadOnlyDictionary<string, TTMethod> methods
        {
            get
            {
                return _methods;
            }
        }

        public IReadOnlyDictionary<string, TTVar> vars
        {
            get
            {
                return _vars;
            }
        }
        public void AddNameSpace(TTNameSpace _namespace)
        {
            if (this._namespaces == null)
                this._namespaces = new Dictionary<string, TTNameSpace>();

            this._namespaces.Add(_namespace.name, _namespace);
        }

        public void AddMethod(TTMethod method)
        {
            if (this._methods == null)
                this._methods = new Dictionary<string, TTMethod>();

            this._methods.Add(method.name, method);
        }

        public void AddType(TTType type)
        {
            if (this._types == null)
                this._types = new Dictionary<string, TTType>();

            this._types.Add(type.name, type);
        }

        public void AddVar(TTVar var)
        {
            if (this._vars == null)
                this._vars = new Dictionary<string, TTVar>();

            this._vars.Add(var.name, var);
        }
        public bool FindMethod(string id, out TTMethod method)
        {
            method = null;
            if (this._methods == null)
                return false;
            return this._methods.TryGetValue(id, out method);
        }
        public bool FindVar(string id, out TTVar var)
        {
            var = null;
            if (this._vars == null)
                return false;
            return this._vars.TryGetValue(id, out var);
        }
        public bool FindType(string id, out TTType type)
        {
            type = null;
            if (this.types == null)
                return false;
            return this.types.TryGetValue(id, out type);
        }
        public bool FindNamespace(string id, out TTNameSpace _namespace)
        {
            _namespace = null;
            if (this.namespaces == null)
                return false;
            return this.namespaces.TryGetValue(id, out _namespace);
        }
        public bool FindMember(string id, out IMember member)
        {
            if (FindMethod(id, out var _m))
            {
                member = _m;
                return true;
            }
            else if (FindVar(id, out var _v))
            {
                member = _v;
                return true;
            }
            else
            {
                member = null;
                return false;
            }
        }
        public bool FindSubContainer(string id, out IContainer container)
        {
            if (FindType(id, out var _m))
            {
                container = _m;
                return true;
            }
            else if (FindNamespace(id, out var _v))
            {
                container = _v;
                return true;
            }
            else
            {
                container = null;
                return false;
            }
        }



    }
}
